package org.apache.dolphinscheduler.api.controller;

import static org.apache.dolphinscheduler.api.enums.Status.QUERY_USER_AUTH_FAIL;

import javax.servlet.http.HttpServletResponse;

import org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.exceptions.ApiException;
import org.apache.dolphinscheduler.api.service.UserAuthenticationService;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.entity.UserAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "USER_AUTH_TAG")
@RestController
@RequestMapping("/user-auth")
public class UserAuthController extends BaseController {
	

	@Autowired
	private UserAuthenticationService userAuthenticationService;
	
	@Operation(summary = "queryUserAuthList", description = "QUERY_USER_AUTH_LIST_NOTES")
    @GetMapping(value = "/{user_id}/list")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_USER_AUTH_FAIL)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result queryUserAuthList(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
    		@PathVariable("user_id") Integer user_id) {
		Result<Object> result = new Result<>();
		result.setData(userAuthenticationService.queryAuthByUserId(user_id));
        
        result.setCode(Status.SUCCESS.getCode());
    	result.setMsg(Status.SUCCESS.getMsg());
        return result;
    }
	
	@Operation(summary = "auditUserAuth", description = "AUDIT_USER_AUTH")
    @PostMapping(value = "/audit/{user_id}")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_USER_AUTH_FAIL)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result auditUserAuth(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
    		@PathVariable("user_id") Integer user_id, @RequestBody UserAuthentication auth) {
		Result<Object> result = new Result<>();
		if(auth.getAuthStatus() == null) {
			result.setCode(Status.AUDIT_USER_PARAM_ERROR.getCode());
        	result.setMsg(Status.AUDIT_USER_PARAM_ERROR.getMsg());
	        return result;
		}
		
        return userAuthenticationService.auditUserAuth(loginUser, user_id, auth.getAuthStatus(), auth.getRemark());
    }
	
	@Operation(summary = "userAuthInfo", description = "USER_AUTH_INFO")
    @GetMapping(value = "/{id}/info")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_USER_AUTH_FAIL)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result userAuthInfo(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
    		@PathVariable("id") Integer id) {
		Result<Object> result = new Result<>();
		result.setData(userAuthenticationService.getUserAuthById(id));
        
        result.setCode(Status.SUCCESS.getCode());
    	result.setMsg(Status.SUCCESS.getMsg());
        return result;
    }
	
	@Operation(summary = "userAuthInfoByUserId", description = "USER_AUTH_INFO")
    @GetMapping(value = "/{user_id}/authInfo")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_USER_AUTH_FAIL)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result userAuthInfoByUserId(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
    		@PathVariable("user_id") Integer id, @RequestParam("auditStatus") Integer auditStatus) {
		Result<Object> result = new Result<>();
		result.setData(userAuthenticationService.getUserAuthentication(id, auditStatus));
        
        result.setCode(Status.SUCCESS.getCode());
    	result.setMsg(Status.SUCCESS.getMsg());
        return result;
    }
	
	@Operation(summary = "saveUserAuth", description = "SAVE_USER_AUTH")
    @PostMapping()
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_USER_AUTH_FAIL)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result saveUserAuth(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, @RequestBody UserAuthentication auth) {
		
        return userAuthenticationService.addUserAuth(loginUser, auth);
    }
	
	@Operation(summary = "fileUpload", description = "FILE_UPLOAD")
	@Parameters({
        @Parameter(name = "file", description = "RESOURCE_FILE", required = true, schema = @Schema(implementation = MultipartFile.class))
	})
    @PostMapping("/upload")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_USER_AUTH_FAIL)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result uploadFile(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
    		@RequestParam("file") MultipartFile file) {
        return userAuthenticationService.uploadFile(loginUser, file);
    }
	
	@Operation(summary = "getFile", description = "GET_FILE")
    @GetMapping("/getFile")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_USER_AUTH_FAIL)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result getFile(HttpServletResponse resp,
    		@RequestParam("fileName") String fileName) {
        return userAuthenticationService.getFile(resp, fileName);
    }
}
